void main() {
 // Without null safety:
String ?notAString = null;
print(notAString?.length);
  bad(null);
  bool isEmpty(String? string) => string?.length == 0; // 使用可空参数
 isEmpty(null);
 Object maybeString = 'it is';
  requireStringNotObject(maybeString as String); 




 //https://dart.cn/null-safety/#null-safety-principles
 //https://dart.cn/null-safety/#introduction-through-examples
  // 非空变量
  var i = 42; // 推断为 int
  String name = "Dar"; // 非空 String

  // 可空变量
  int? aNullableInt = null; // 可空 int

  // 使用可空变量
  if (aNullableInt != null) {
    print(aNullableInt + 1); // 安全操作
  } else {
    print("aNullableInt is null");
  }

  // 非空变量不能为 null
  // name = null; // 错误：非空 String 不能为 null



var coffee = Coffee();
  coffee.heat();
  coffee.serve();


Box<String>('a string');
  Box<int?>(null);

}


// Using null safety:
void makeCoffee(String coffee, [String? dairy]) {
  if (dairy != null) {
    print('$coffee with $dairy');
  } else {
    print('Black $coffee');
  }
}


// Without null safety:
bool isEmpty(String string) => string.length == 0;

void bad(String? maybeString) {
  print(maybeString?.length);
}


// Without null safety:
void requireStringNotObject(String definitelyString) {
  print(definitelyString.length);
}


//https://dart.cn/null-safety/understanding-null-safety/#never-for-unreachable-code
// Using null safety:
class Point {
  final double x, y;
 Point(this.x, this.y);
  bool operator ==(Object other) {
    if (other is! Point) return false; // Type check
    return x == other.x && y == other.y;
  }
@override
  int get hashCode => x.hashCode ^ y.hashCode; 
  // Constructor and hashCode...
}

//https://dart.cn/null-safety/understanding-null-safety/#working-with-nullable-fields
// Using null safety:
class Coffee {
  void heat() {
    print('Heating coffee');
  }

  void serve() {
    print('Serving coffee');
  }
}
//https://dart.cn/null-safety/understanding-null-safety/#nullability-and-generics
// Using null safety:
class Box<T> {
  final T value;

  Box(this.value); // Constructor

  @override
  String toString() => 'Box($value)';
}


//https://dart.cn/null-safety/understanding-null-safety/#definite-assignment-analysis
// Using null safety:
int tracingFibonacci(int n) {
  final int result;
  if (n < 2) {
    result = n;
  } else {
    result = tracingFibonacci(n - 2) + tracingFibonacci(n - 1);
  }

  print(result);
  return result;
}

//https://dart.cn/null-safety/understanding-null-safety/#type-promotion-on-null-checks
// Using null safety:
String makeCommand(String executable, [List<String>? arguments]) {
  var result = executable;
  if (arguments != null) {
    result += ' ' + arguments.join(' ');
  }
  return result;
}


//https://dart.cn/null-safety/understanding-null-safety/#unnecessary-code-warnings
// Using null safety:
String checkList(List<Object> list) {
  if (list.isEmpty ?? false) {
    return 'Got nothing';
  }
  return 'Got something';
}


//https://dart.cn/null-safety/understanding-null-safety/#non-null-assertion-operator
// Using null safety, incorrectly:
class HttpResponse {
  final int code;
  final String? error;

  HttpResponse.ok()
      : code = 200,
        error = null;
  HttpResponse.notFound()
      : code = 404,
        error = 'Not found';

  @override
  String toString() {
    if (code == 200) return 'OK';
    return 'ERROR $code ${error!.toUpperCase()}';
  }
}


//https://dart.cn/null-safety/understanding-null-safety/#nullability-and-generics
// Using null safety:
class Interval<T extends num?> {
  T min, max;

  Interval(this.min, this.max);

  bool get isEmpty {
    var localMin = min;
    var localMax = max;

    // No min or max means an open-ended interval.
    if (localMin == null || localMax == null) return false;
    return localMax <= localMin;
  }
}